package com.dome.redis.utils;


import com.dome.util.ObjectUtils;
import com.dome.util.StringUtils;
import com.dome.util.spring.SpringBeanUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import redis.clients.jedis.exceptions.JedisException;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Jedis Cache 工具类
 * 
 * @author jinjie.chen
 * @version 2020-6-29
 */
public class JedisUtils {

	private static Logger logger = LoggerFactory.getLogger(JedisUtils.class);

	private static JedisPool jedisPool = SpringBeanUtils.getBean("defaultJedisPool");


	/**
	 * 获取缓存
	 * @param key 键
	 * @return 值
	 */
	public static String get(final String key) {
		String value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				value = jedis.get(key);
				value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
				if (logger.isDebugEnabled()) {
				    logger.debug("get {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("get {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 获取缓存
	 * @param key 键
	 * @return 值
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getObject(final String key) {
		if(key==null) {
			return null;
		}
		Object value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
//			if (jedis.exists(getBytesKey(key))) {
				value = toObject(jedis.get(getBytesKey(key)));
				if (logger.isDebugEnabled()) {
				    logger.debug("getObject {} = {}", key, value);
				}
//			}
		} catch (final Exception e) {
			logger.warn("getObject {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return (T)value;
	}

	/**
	 * 设置缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static String set(final String key, final String value, final int cacheSeconds) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.set(key, value);
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("set {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("set {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}
	/**
	 * 设置缓存
	 * @param key 键
	 * @param value 值
	 * @param cachetime 超时时间，0为不超时
	 * @param timeUnit 时分秒天转换
	 * @return
	 */
	public static String set(final String key, final String value, final int cachetime, final TimeUnit timeUnit) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.set(key, value);
			if (cachetime != 0) {
				jedis.expire(key, (int) timeUnit.toSeconds(cachetime));
			}
			if (logger.isDebugEnabled()) {
				logger.debug("set {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("set {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}
	/**
	 * 设置缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static String setObject(final String key, final Object value, final int cacheSeconds) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.set(getBytesKey(key), toBytes(value));
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setObject {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setObject {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 获取List缓存
	 * @param key 键
	 * @return 值
	 */
	public static List<String> getList(final String key) {
		List<String> value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				value = jedis.lrange(key, 0, -1);
				if (logger.isDebugEnabled()) {
				    logger.debug("getList {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("getList {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 获取List缓存
	 * @param key 键
	 * @return 值
	 */
	public static <T> List<T> getObjectList(final String key) {
		List<T> value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))) {
				final List<byte[]> list = jedis.lrange(getBytesKey(key), 0, -1);
				value = Lists.newArrayList();
				for (final byte[] bs : list){
					value.add(toObject(bs));
				}
				if (logger.isDebugEnabled()) {
				    logger.debug("getObjectList {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("getObjectList {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 设置List缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static long setList(final String key, final List<String> value, final int cacheSeconds) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				jedis.del(key);
			}
			result = jedis.rpush(key, (String[])value.toArray());
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setList {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setList {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 设置List缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static long setObjectList(final String key, final List<?> value, final int cacheSeconds) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))) {
				jedis.del(key);
			}

			final int size = value.size();
			final byte[][] values = new byte[size][];
			for (int i = 0 ; i < size; i++){
			    values[i] = toBytes(value.get(i));
			}
			result = jedis.rpush(getBytesKey(key), values);
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setObjectList {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setObjectList {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 向List缓存中添加值
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public static long listAdd(final String key, final String... value) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.rpush(key, value);
			if (logger.isDebugEnabled()) {
			    logger.debug("listAdd {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("listAdd {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 向List缓存中添加值
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public static long listObjectAdd(final String key, final Object... value) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			final int size = value.length;
            final byte[][] values = new byte[size][];
            for (int i = 0 ; i < size; i++){
                values[i] = toBytes(value[i]);
            }
			result = jedis.rpush(getBytesKey(key), values);
			if (logger.isDebugEnabled()) {
			    logger.debug("listObjectAdd {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("listObjectAdd {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 获取缓存
	 * @param key 键
	 * @return 值
	 */
	public static Set<String> getSet(final String key) {
		Set<String> value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				value = jedis.smembers(key);
				if (logger.isDebugEnabled()) {
				    logger.debug("getSet {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("getSet {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 获取缓存
	 * @param key 键
	 * @return 值
	 */
	public static Set<Object> getObjectSet(final String key) {
		Set<Object> value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))) {
				value = Sets.newHashSet();
				final Set<byte[]> set = jedis.smembers(getBytesKey(key));
				for (final byte[] bs : set){
					value.add(toObject(bs));
				}
				if (logger.isDebugEnabled()) {
				    logger.debug("getObjectSet {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("getObjectSet {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 设置Set缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static long setSet(final String key, final Set<String> value, final int cacheSeconds) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				jedis.del(key);
			}
			result = jedis.sadd(key, (String[])value.toArray());
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setSet {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setSet {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 设置Set缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static long setObjectSet(final String key, final Set<Object> value, final int cacheSeconds) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))) {
				jedis.del(key);
			}
			final int size = value.size();
            final byte[][] values = new byte[size][];
            int i = 0;
            for (final Object o: value){
                values[i++] = toBytes(o);
            }
            result = jedis.rpush(getBytesKey(key), values);
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setObjectSet {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setObjectSet {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 向Set缓存中添加值
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public static long setSetAdd(final String key, final String... value) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.sadd(key, value);
			if (logger.isDebugEnabled()) {
			    logger.debug("setSetAdd {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setSetAdd {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 向Set缓存中添加值
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public static long setSetObjectAdd(final String key, final Object... value) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			final int size = value.length;
            final byte[][] values = new byte[size][];
            for (int i = 0; i < size; i++){
                values[i] = toBytes(value[i]);
            }
            result = jedis.rpush(getBytesKey(key), values);
			if (logger.isDebugEnabled()) {
			    logger.debug("setSetObjectAdd {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setSetObjectAdd {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 获取Map缓存
	 * @param key 键
	 * @return 值
	 */
	public static Map<String, String> getMap(final String key) {
		Map<String, String> value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				value = jedis.hgetAll(key);
				if (logger.isDebugEnabled()) {
				    logger.debug("getMap {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("getMap {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 获取Map缓存
	 * @param key 键
	 * @return 值
	 */
	public static Map<String, Object> getObjectMap(final String key) {
		Map<String, Object> value = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))) {
				value = Maps.newHashMap();
				final Map<byte[], byte[]> map = jedis.hgetAll(getBytesKey(key));
				for (final Map.Entry<byte[], byte[]> e : map.entrySet()){
					value.put(StringUtils.toString(e.getKey()), toObject(e.getValue()));
				}
				if (logger.isDebugEnabled()) {
				    logger.debug("getObjectMap {} = {}", key, value);
				}
			}
		} catch (final Exception e) {
			logger.warn("getObjectMap {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return value;
	}

	/**
	 * 设置Map缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static String setMap(final String key, final Map<String, String> value, final int cacheSeconds) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(key)) {
				jedis.del(key);
			}
			result = jedis.hmset(key, value);
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setMap {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setMap {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 设置Map缓存
	 * @param key 键
	 * @param value 值
	 * @param cacheSeconds 超时时间，0为不超时
	 * @return
	 */
	public static String setObjectMap(final String key, final Map<String, Object> value, final int cacheSeconds) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))) {
				jedis.del(key);
			}
			final Map<byte[], byte[]> map = Maps.newHashMap();
			for (final Map.Entry<String, Object> e : value.entrySet()){
				map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
			}
			result = jedis.hmset(getBytesKey(key), map);
			if (cacheSeconds != 0) {
				jedis.expire(key, cacheSeconds);
			}
			if (logger.isDebugEnabled()) {
			    logger.debug("setObjectMap {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("setObjectMap {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 向Map缓存中添加值
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public static String mapPut(final String key, final Map<String, String> value) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.hmset(key, value);
			if (logger.isDebugEnabled()) {
			    logger.debug("mapPut {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("mapPut {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 *
	 * @param key
	 * @param field
	 * @return
	 */
	public static String mapGet(final String key, final String field) {
	    String result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hget(key, field);
            if (logger.isDebugEnabled()) {
                logger.debug("mapGet {} = {}", key, field);
            }
        } catch (final Exception e) {
            logger.warn("mapGet {} = {}", key, field, e);
        } finally {
            returnResource(jedis);
        }
        return result;
	}

	/**
     * 从Map缓存中取值
     * @param key 键
     * @param fields 字段
     * @return
     */
    public static List<String> mapGet(final String key, final String... fields) {
        List<String> result = null;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.hmget(key, fields);
            if (logger.isDebugEnabled()) {
                logger.debug("mapGet {} = {}", key, fields);
            }
        } catch (final Exception e) {
            logger.warn("mapGet {} = {}", key, fields, e);
        } finally {
            returnResource(jedis);
        }
        return result;
    }

	/**
	 * 向Map缓存中添加值
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public static String mapObjectPut(final String key, final Map<String, Object> value) {
		String result = null;
		Jedis jedis = null;
		try {
			jedis = getResource();
			final Map<byte[], byte[]> map = Maps.newHashMap();
			for (final Map.Entry<String, Object> e : value.entrySet()){
				map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
			}
			result = jedis.hmset(getBytesKey(key), map);
			if (logger.isDebugEnabled()) {
			    logger.debug("mapObjectPut {} = {}", key, value);
			}
		} catch (final Exception e) {
			logger.warn("mapObjectPut {} = {}", key, value, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
     * 从Map缓存中取值
     * @param key 键
     * @param fields
     * @return
     */
    public static List<Object> mapObjectGet(final String key, final String... fields) {
        List<Object> result = new ArrayList<Object>();
        Jedis jedis = null;
        try {
            jedis = getResource();
            final int size = fields.length;
            final byte[][] byteFields = new byte[size][];
            for (int i = 0; i < size; i++){
                byteFields[i] = getBytesKey(fields[i]);
            }
            final List<byte[]> objects = jedis.hmget(getBytesKey(key), byteFields);
            result = objects.stream().map(JedisUtils::toObject).collect(Collectors.toList());
            if (logger.isDebugEnabled()) {
                logger.debug("mapObjectGet {} = {}", key, fields);
            }
        } catch (final Exception e) {
            logger.warn("mapObjectGet {} = {}", key, fields, e);
        } finally {
            returnResource(jedis);
        }
        return result;
    }


	/**
	 * 移除Map缓存中的值
	 * @param key 键
	 * @param mapKey 值
	 * @return
	 */
	public static long mapRemove(final String key, final String mapKey) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.hdel(key, mapKey);
			if (logger.isDebugEnabled()) {
			    logger.debug("mapRemove {}  {}", key, mapKey);
			}
		} catch (final Exception e) {
			logger.warn("mapRemove {}  {}", key, mapKey, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 移除Map缓存中的值
	 * @param key 键
	 * @param mapKey 值
	 * @return
	 */
	public static long mapObjectRemove(final String key, final String mapKey) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.hdel(getBytesKey(key), getBytesKey(mapKey));
			if (logger.isDebugEnabled()) {
			    logger.debug("mapObjectRemove {}  {}", key, mapKey);
			}
		} catch (final Exception e) {
			logger.warn("mapObjectRemove {}  {}", key, mapKey, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 判断Map缓存中的Key是否存在
	 * @param key 键
	 * @param mapKey 值
	 * @return
	 */
	public static boolean mapExists(final String key, final String mapKey) {
		boolean result = false;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.hexists(key, mapKey);
			if (logger.isDebugEnabled()) {
			    logger.debug("mapExists {}  {}", key, mapKey);
			}
		} catch (final Exception e) {
			logger.warn("mapExists {}  {}", key, mapKey, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 判断Map缓存中的Key是否存在
	 * @param key 键
	 * @param mapKey 值
	 * @return
	 */
	public static boolean mapObjectExists(final String key, final String mapKey) {
		boolean result = false;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.hexists(getBytesKey(key), getBytesKey(mapKey));
			if (logger.isDebugEnabled()) {
			    logger.debug("mapObjectExists {}  {}", key, mapKey);
			}
		} catch (final Exception e) {
			logger.warn("mapObjectExists {}  {}", key, mapKey, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 删除缓存
	 * @param key 键
	 * @return
	 */
	public static long del(final String key) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.del(key);
			logger.debug("del {}", key);
		} catch (final Exception e) {
			logger.warn("del {}", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 删除缓存
	 * @param key 键
	 * @return
	 */
	public static long delList(final String key) {

		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			// 游标初始值为0
			String cursor = ScanParams.SCAN_POINTER_START;
			ScanParams scanParams = new ScanParams();
			scanParams.match(key);// 匹配以 test:xttblog:* 为前缀的 key
			scanParams.count(1000);
			while (true){
				//使用scan命令获取500条数据，使用cursor游标记录位置，下次循环使用
				ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
				cursor = scanResult.getStringCursor();// 返回0 说明遍历完成
				List<String> list = scanResult.getResult();
				long t1 = System.currentTimeMillis();
				if(!CollectionUtils.isEmpty(list)) {
					String[] keys = new String[list.size()];
					for(int i=0;i<list.size();i++) {
						keys[i] = list.get(i);
					}
					jedis.del(keys);
				}

				long t2 = System.currentTimeMillis();
//				System.out.println("删除" + list.size()
//						+ "条数据，耗时: " + (t2-t1) + "毫秒,cursor:" + cursor);
				if ("0".equals(cursor)){
					break;
				}
			}
		} catch (final Exception e) {
			logger.warn("del {}", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;

	}
	/**
	 * 删除缓存
	 * @param key 键
	 * @return
	 */
	public static long delObject(final String key) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			if (jedis.exists(getBytesKey(key))){
				result = jedis.del(getBytesKey(key));
				logger.debug("delObject {}", key);
			}else{
				logger.debug("delObject {} not exists", key);
			}
		} catch (final Exception e) {
			logger.warn("delObject {}", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}
	/**
	 * 缓存是否存在
	 * @param key 键
	 * @return
	 */
	public static boolean exists(final String key) {
		boolean result = false;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.exists(key);
			logger.debug("exists {}", key);
		} catch (final Exception e) {
			logger.warn("exists {}", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 缓存是否存在
	 * @param key 键
	 * @return
	 */
	public static boolean existsObject(final String key) {
		boolean result = false;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.exists(getBytesKey(key));
			logger.debug("existsObject {}", key);
		} catch (final Exception e) {
			logger.warn("existsObject {}", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	/**
	 * 获取资源
	 * @return
	 * @throws JedisException
	 */
	public static Jedis getResource() throws JedisException {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
		} catch (final JedisException e) {
			logger.warn("getResource.", e);
			returnBrokenResource(jedis);
			throw e;
		}
		return jedis;
	}

	/**
	 * 归还资源
	 * @param jedis
	 */
	@SuppressWarnings("deprecation")
	public static void returnBrokenResource(final Jedis jedis) {
		if (jedis != null) {
//			jedisPool.returnBrokenResource(jedis);
			jedis.close();
		}
	}

	/**
	 * 释放资源
	 * @param jedis
	 */
	@SuppressWarnings("deprecation")
	public static void returnResource(final Jedis jedis) {
		if (jedis != null) {
//			jedisPool.returnResource(jedis);
			jedis.close();
		}
	}

	/**
	 * 获取byte[]类型Key
	 * @param object
	 * @return
	 */
	public static byte[] getBytesKey(final Object object){
		if(object instanceof String){
    		return StringUtils.getBytes((String)object);
    	}else{
    		return ObjectUtils.serialize(object);
    	}
	}

	/**
	 * 获取byte[]类型Key
	 * @param key
	 * @return
	 */
	public static Object getObjectKey(final byte[] key){
		try{
			return StringUtils.toString(key);
		}catch(final UnsupportedOperationException uoe){
			try{
				return JedisUtils.toObject(key);
			}catch(final UnsupportedOperationException uoe2){
				uoe2.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * Object转换byte[]类型
	 * @param object
	 * @return
	 */
	public static byte[] toBytes(final Object object){
    	return ObjectUtils.serialize(object);
	}

	/**
	 * byte[]型转换Object
	 * @param bytes
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T toObject(final byte[] bytes){
		return (T)ObjectUtils.unserialize(bytes);
	}

	/**
	 *
	 * @param keyPartten
	 * @return
	 */
	public static Integer keysCount(final String keyPartten) {
		final Optional<Set<String>> keysOpt = Optional.ofNullable(keys(keyPartten));
		final Optional<Integer> keysCount = keysOpt.map(keys -> keys.size());
		return keysCount.orElse(0);
	}

	public static Set<String> keys(final String keyPartten) {
		Jedis jedis = null;
		Set<String> keys = null;
		try {
			jedis = getResource();
			keys = jedis.keys(keyPartten);
		}
		catch (final Exception e) {
			logger.warn("keys {}", keyPartten, e);
		}
		finally {
			returnResource(jedis);
		}
		return keys;
	}
	/**
	 * 值自动增加
	 * @param key 键
	 * @return
	 */
	public static long incrBy(final String key,final long number) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.incrBy(key,number);
			if (logger.isDebugEnabled()) {
				logger.debug("incr {}", key);
			}
		} catch (final Exception e) {
			logger.warn("incr {} ", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}
	/**
	 * 值自动增加
	 * @param key 键
	 * @return
	 */
	public static long incr(final String key) {
		long result = 0;
		Jedis jedis = null;
		try {
			jedis = getResource();
			result = jedis.incr(key);
			if (logger.isDebugEnabled()) {
			    logger.debug("incr {}", key);
			}
		} catch (final Exception e) {
			logger.warn("incr {} ", key, e);
		} finally {
			returnResource(jedis);
		}
		return result;
	}

	public static Long expire(String key, int seconds) {
        long result = 0;
        Jedis jedis = null;
        try {
            jedis = getResource();
            result = jedis.expire(key, seconds);
            if (logger.isDebugEnabled()) {
                logger.debug("expire {}", seconds);
            }
        } catch (final Exception e) {
            logger.warn("expire {} ", key, e);
        } finally {
            returnResource(jedis);
        }
        return result;
    }


}
